home *** CD-ROM | disk | FTP | other *** search
- /*
- * Starter for REALbasic 2.0 plugins
- *
- * Currently, this code shows how to add new global methods and how
- * to create or extend classes to RB.
- * Creating Controls is not shown in here - see the sample projects
- * in RB's plugin SDK for that.
- *
- * The accompanying project file was created using CodeWarrior Pro 4
- * with the latest updates from Metrowerks' FTP Site (including IDE 3.3).
- *
- * This code is freeware, you may use and extend it as you like.
- * It was written on Nov 21, 99 by Thomas Tempelmann.
- * Updated Jan 18, 2000 by TT: Verified with RB 2.1a25 that classes work
- * now in x86 plugins, too.
- * Updated Jan 28, 2000 by TT: ("Ruslan special") Now also initializes
- * static C++ constructors.
- * Updated Feb 1, 2000 by TT: Now also shows how to pass Boolean and
- * Double arguments. Also added "#pragma mpwc on" to this and to the
- * "PluginMain.cpp" for 68K compiles, and disabled the global MPW C
- * calling option in the project settings for "68K Processor".
- * Removed the "far" modifier from a function prototype to avoid an
- * error msg from the Pro 5's compiler.
- *
- * More RB-related stuff can be found here: <http://www.tempel.org/rb/>
- *
- * Enjoy and contribute!
- */
-
-
- /*
- * -----------
- * Attention
- * -----------
- *
- * In case you want to create plugins that can be used under Windows, too:
- *
- * Versions of RB before 2.1a24 (that is, RB versions before January 2000)
- * did not handle Windows plugins correctly: It was impossible to use x86
- * (Windows) plugins that added a new class. If you tried to call any method
- * or property of a new class from a plugin, you'll get a crash in your
- * Windows app. RB 2.1a25 has this problem fixed.
- *
- * That means: If you re-distribute plugins for Windows, you have to let
- * your users know that they cannot use them with RB versions before 2.1a24.
- */
-
- //--------------------
- // Your includes here
- //--------------------
-
- #include <string.h> // this and any other includes must come _before_ the "pragma mpwc on"!
- #ifndef WIN32
- #include <MacMemory.h>
- #else
- //static void DebugStr(unsigned char* p) {}
- //static void Debugger() {}
- #endif
-
- //-------------------------
- // RB header includes here
- //-------------------------
-
- // Attention - if you include any other headers, like those from the C stdlib,
- // or PowerPlant, you must place those includes _before_ the following
- // pragma that turns on mpwc calling conventions, or you might get crashes in
- // 68K plugins!
- #if TARGET_CPU_68K
- //#pragma mpwc on
- #endif
-
- #include "rb_plugin.h" // this include must come _after_ the "pragma mpwc on"!
-
-
- //-----------------------
- // Some type definitions
- //-----------------------
-
- // "RBinteger" represents a RB "Integer" type:
-
- typedef long RBinteger;
-
- // "RBboolean" represents a RB "Boolean" type (when passed as a parameter or returned from a function):
-
- //typedef Boolean RBboolean;
-
- // "RBdouble" represents a RB "Double" type:
-
- #if TARGET_CPU_68K
- typedef Float80 RBdouble; // Attention: for this to work, "Floating Point" in the "68K Processor" options must be set to "SANE".
- #else
- typedef double RBdouble;
- #endif
-
- /*
- * Note: Passing Singles to plugin functions is currently (RB 2.1a26) not correctly supported
- * in RB for 68K code, so I suggest to always only use Doubles as parameters!
- */
-
-
-
- //-----------------------
- // Add global RB methods
- //-----------------------
-
- static RBinteger sampleIntFunc (RBinteger a, RBinteger b)
- // Adds the two passed values and returns the result
- {
- return a + b;
- }
-
- static RBdouble sampleDblFunc (RBdouble a, RBdouble b)
- {
- return a + b;
- }
-
-
- static void copyBytes (char const* from, char* to, long amount)
- // This is just a little helper function to copy some bytes
- // (Attention: this may not work when the memory of "to" and "from"
- // is overlapping!)
- {
- while (amount-- > 0) {
- *to++ = *from++;
- }
- }
-
- // For examples on handling other RB data types, such as Double and Boolean,
- // see the code for handling class properties further below.
-
- static REALstring sampleStrFunc (REALstring a, REALstring b)
- // Concatenates the two strings and returns the result
- {
- // get the length of the two strings
- long la, lb;
- la = a->Length();
- lb = b->Length();
-
- // create a new string object that is large enough to hold the sum of the two strings
- REALstring str = REALBuildString (nil, la + lb);
-
- // now copy the two strings' contents into the new string buffer
- copyBytes (a->CString(), (char*)str->CString(), la);
- copyBytes (b->CString(), (char*)str->CString() + la, lb);
-
- return str;
- }
-
- static REALmethodDefinition pluginMethodArray[] = {
- { (REALproc) sampleIntFunc, REALnoImplementation, "SampleIntFunc(A as Integer, B as Integer) as Integer" },
- { (REALproc) sampleDblFunc, REALnoImplementation, "SampleDoubleFunc(A as Double, B as Double) as Double" },
- { (REALproc) sampleStrFunc, REALnoImplementation, "SampleStrFunc(A as String, B as String) as String" },
- };
-
-
- //------------------------------------------------------
- // Create a new RB class or extend an existing RB class
- //------------------------------------------------------
-
-
- // If you want to create a new class, set the following macro
- // to 0;
- // If you want to extend an existing RB class, such as FolderItem,
- // Date or Application, set the value to 1:
-
- #define doExtentTheClass 0 // if 0, then it'll create a new class instead
-
-
- extern REALclassDefinition sampleClass; // forward declaration
-
-
- /*
- * The following structure defines internal storage space for your
- * class. This space is not automatically visible to the user, but
- * only if you add property accessor routines like the ones below
- * (see sampleIntGetter and following).
- */
-
- struct sampleClassData
- {
- // Note: If you _extend_ a class, the properties here will not be zeroed,
- // nor will the constructor be called. That means that these properties
- // will not get any defined values - they may contain random data if
- // the class is instantiated! I consider this a bug in RB.
-
- long aInteger;
- Boolean aBoolean;
- double aDouble;
- };
-
-
- /*
- * The following code implements the constructor and destructor of the class.
- *
- * Note that those will only be called when you define a _new_ class, but not
- * if you extends a class (this is a bug in RB 2.1a25 and might perhaps get
- * fixed later).
- */
-
- static void sampleClassConstructor (REALobject instance)
- {
- ClassData (sampleClass, instance, sampleClassData, me);
-
- // you can initialize objects of "me" here ...
-
- me->aInteger = 1234;
- }
-
- static void sampleClassDestructor (REALobject instance)
- {
- ClassData (sampleClass, instance, sampleClassData, me);
-
- // close & dispose objects of "me" here
- //
- // (e.g., if you opened a file or allocated memory, you need to release it here again!)
- }
-
-
- /*
- * The following code shows how to deal with RB's Integer values (which is quite simple)
- */
-
- static RBinteger sampleIntGetter (REALobject instance, long param)
- // This is called when RB reads a property of your class
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- return me->aInteger;
- }
-
- static void sampleIntSetter (REALobject instance, long param, RBinteger value)
- // This is called when RB assigns a value to a property of your class
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- me->aInteger = value;
- }
-
-
- /*
- * The following code shows how to deal with RB's Boolean values. Note that RB
- * passes its Boolean arguments as 32 bit (long) values. Also note that beta versions
- * of RB 2.1 have a bug in their 68K code that will instead pass them as 8 bit values.
- * RB 2.0.2 and before did not have this bug.
- * This bug should be fixed before the final 2.1 comes out, hopefully.
- */
-
- static Boolean sampleBoolGetter (REALobject instance, long param)
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- return me->aBoolean; // 1 is "true", 0 is "false"
- }
-
- static void sampleBoolSetter (REALobject instance, long param, Boolean value)
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- me->aBoolean = value;
- }
-
-
- /*
- * The following code shows how to deal with RB's Double values - note that 68K code
- * needs a special handling, because in 68K a RB double is a 80 bit value, while in
- * PPC and x86 it is a 64 bit value:
- */
-
- static double sampleDoubleGetter (REALobject instance, long param)
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- return me->aDouble;
- }
-
- static void sampleDoubleSetter (REALobject instance, long param, double value)
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- me->aDouble = value;
- // note for 68K: the 64 bit "double" value is converted into RB's 80 bit "extended" value here
- }
-
-
- /*
- * The following code shows how to implement methods of a class
- */
-
- static void sampleClassMethod (REALobject instance, RBinteger factor)
- // This is called when RB calls a method of your class
- {
- ClassData (sampleClass, instance, sampleClassData, me);
- me->aInteger *= factor;
- }
-
- /*
- * The following structures declare the class and its members
- */
-
- static REALproperty sampleClassProperties[] = {
- { nil, "SampleInt", "Integer", 0, (REALproc) sampleIntGetter, (REALproc) sampleIntSetter, 0 },
- { nil, "SampleBool", "Boolean", 0, (REALproc) sampleBoolGetter, (REALproc) sampleBoolSetter, 0 },
- { nil, "SampleDouble", "Double", 0, (REALproc) sampleDoubleGetter, (REALproc) sampleDoubleSetter, 0 },
- };
-
- static REALmethodDefinition sampleClassMethods[] = {
- // defines a method:
- { (REALproc) sampleClassMethod, REALnoImplementation, "SampleMethod(factor as Integer)"},
- };
-
- static REALclassDefinition sampleClass = {
- kCurrentREALControlVersion,
- #if doExtentTheClass
- "aRBClassName", // <- put the name of the to be extended class here, like "FolderItem"
- #else
- "SampleClass", // <- this is the name of the class you're adding with this plugin
- #endif
- nil,
- sizeof(sampleClassData),
- 0,
- #if doExtentTheClass
- // Unfortunately, for extended classes, we don't get called when an obj is con-/destructed.
- // (this is a current RB restriction and might be changed in a later version, hopefully)
- nil, nil,
- #else
- (REALproc) sampleClassConstructor, (REALproc) sampleClassDestructor,
- #endif
- sampleClassProperties,
- sizeof(sampleClassProperties) / sizeof(REALproperty),
- sampleClassMethods,
- sizeof(sampleClassMethods) / sizeof(REALmethodDefinition),
- nil,
- 0
- };
-
-
- // To initialize the static C++ objects, we must call a special routine
- // that the linker will generate. Here's the preperation for this:
- #ifdef WIN32
- extern "C" far void _RunInit(void);
- #define __InitCode__ _RunInit
- #elif defined(powerc)
- extern "C" void __sinit(void);
- #define __InitCode__ __sinit
- #else // it's 68K
- extern "C" far void __InitCode__ (void);
- #endif
- extern "C" void __destroy_global_chain (void); // This one should be called when
- // the plugin is unloaded - but how?
-
- void PluginEntry (void)
- {
- /*
- * This is the main entry that is called when your plugin is loaded by REALbasic
- * or when a built application that uses your plugin is launched.
- *
- * Here you tell RB about what your plugin provides. Call:
- * • REALRegisterMethod() to add gobal methods
- * • REALRegisterClass() to add new classes
- * • REALRegisterClassExtension() to extent existing classes
- * • REALRegisterControl() to add new controls
- */
-
- __InitCode__ (); // calls constructors for static and global C++ objects
-
- // Use this code to make your global RB methods known to RB:
- for (int i = 0; i < sizeof(pluginMethodArray) / sizeof(REALmethodDefinition); ++i) {
- REALRegisterMethod (&pluginMethodArray[i]);
- }
-
- // Use this code to make any of your class definitions known to RB:
- #if doExtentTheClass
- REALRegisterClassExtension (&sampleClass);
- #else
- #ifdef WIN32
- // #warning "Make sure you use RB 2.1a24 or later to create plugins for Windows!"
- #endif
- REALRegisterClass (&sampleClass);
- #endif
- }
-